﻿//------------------------------------------------------------------------------
//  Namespace: FruitVentDesign.UtilWindows
//  
//  Function： N/A
//  Name： PopupWindow
//  
//  Ver       Time                     Author
//  0.10      2021/6/17 10:54:11     FruitVent
//
//  此代码版权归作者本人FruitVent所有
//  源代码使用协议遵循本仓库的开源协议及附加协议，若本仓库没有设置，则按MIT开源协议授权
//  CSDN博客：https://blog.csdn.net/weixin_39552347
//  源代码仓库：https://gitee.com/fruitvent
//  感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using System.Windows;
using System.Windows.Media.Animation;
using System.Windows.Threading;

namespace FruitVentDesign.UtilWindows
{
    /// <summary>
    /// PopupWindow.xaml 的交互逻辑
    /// </summary>
    public partial class PopupWindow : Windows.GasPocket
    {
        private const double MaxPopupOpacity = 1;
        private const double MinPopupOpacity = 0;

        #region dependency properties
        public static readonly DependencyProperty PopupOpacityProperty =
            DependencyProperty.Register("PopupOpacity", typeof(double), typeof(PopupWindow), new PropertyMetadata((double)0, PopupOpacityChanged));

        public static void PopupOpacityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is PopupWindow window)
            {
                window.PopupOpacityChanged();
            }
        }

        public double PopupOpacity
        {
            get { return (double)GetValue(PopupOpacityProperty); }
            set { SetValue(PopupOpacityProperty, value); }
        }

        #endregion

        private DispatcherTimer _durationTimer = new DispatcherTimer();

        private DoubleAnimation _popupOpacityAnimation = new DoubleAnimation();
        private Storyboard _popupStoryboard = new Storyboard();
        private TimeSpan _fadeSpan;

        public PopupWindow() : this("Popup Message", durationSec: 1, fadeSec: 0.8) { }

        /// <summary>
        /// initialize popup window
        /// </summary>
        /// <param name="message">待显示的信息</param>
        /// <param name="durationSec">窗口保持显示的时间</param>
        /// <param name="fadeSec">窗口淡入淡出的时间</param>
        public PopupWindow(string message, double durationSec = 1, double fadeSec = 0.8)
        {
            InitializeComponent();

            messageTextBlock.Text = message;

            _durationTimer.Tick += Timer_Tick;
            _durationTimer.Interval = TimeSpan.FromSeconds(durationSec);

            _fadeSpan = TimeSpan.FromSeconds(fadeSec);

            _popupStoryboard.Children.Add(_popupOpacityAnimation);
            Storyboard.SetTarget(_popupOpacityAnimation, this);
            Storyboard.SetTargetProperty(_popupOpacityAnimation, new PropertyPath(PopupOpacityProperty));

            FadeIn();
        }

        /// <summary>
        /// fade in window
        /// </summary>
        private void FadeIn()
        {
            _popupOpacityAnimation.From = MinPopupOpacity;
            _popupOpacityAnimation.To = MaxPopupOpacity;
            _popupOpacityAnimation.Duration = _fadeSpan;

            _popupStoryboard.Begin(this);
        }

        /// <summary>
        /// fade out window
        /// </summary>
        private void FadeOut()
        {
            _popupOpacityAnimation.From = MaxPopupOpacity;
            _popupOpacityAnimation.To = MinPopupOpacity;
            _popupOpacityAnimation.Duration = _fadeSpan;

            _popupStoryboard.Begin(this);
        }

        /// <summary>
        /// fade out when timer tick
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Timer_Tick(object sender, EventArgs e)
        {
            // stop duration timer
            _durationTimer.Stop();
            // Console.WriteLine("fade out");
            FadeOut();
        }

        /// <summary>
        /// a. synchronize Opacity with PopupOpacity.
        /// b. start duration timer when reach max vlaue.
        /// c. close window when reach min value.
        /// </summary>
        private void PopupOpacityChanged()
        {
            // update Opcity
            Opacity = PopupOpacity;

            if (PopupOpacity == MaxPopupOpacity)
            {
                // Console.WriteLine("reach max popup opacity");
                // now window is completely visible, start the duration timer
                _durationTimer.Start();
            }
            else if (PopupOpacity == MinPopupOpacity)
            {
                // Console.WriteLine("reach min popup opacity");
                // now window is completely invisible, close it.
                Close();
            }
        }
    }
}
